package com.zxm.web.controller.message;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Collection;
import java.util.Date;

/**
 * @Author silence.Z
 * @Date 2022/8/29 9:42
 * @PackageName:com.zxm.web.controller.message
 * @ClassName: PollingController
 * @Description: 长轮询的方式实现消息推送
 * @Version 1.0
 */
@Controller
@RequestMapping("/polling")
public class PollingController {

	/**
	 * 	存放监听某个Id的长轮询集合
	 *  线程同步结构
	 */
	public static Multimap<String, DeferredResult<String>> watchRequests = Multimaps.synchronizedMultimap(HashMultimap.create());

	/**
	 * 设置监听
	 */
	@GetMapping(path = "watch/{id}")
	@ResponseBody
	public DeferredResult<String> watch(@PathVariable String id) {
		// 延迟对象设置超时时间(100秒)
		DeferredResult<String> deferredResult = new DeferredResult<>(100000L);
		// 异步请求完成时移除 key，防止内存溢出
		deferredResult.onCompletion(() -> {
			watchRequests.remove(id, deferredResult);
		});
		// 注册长轮询请求
		watchRequests.put(id, deferredResult);
		return deferredResult;
	}

	/**
	 * 变更数据
	 */
	@GetMapping(path = "publish/{id}")
	@ResponseBody
	public String publish(@PathVariable String id) {
		// 数据变更 取出监听ID的所有长轮询请求，并一一响应处理
		if (watchRequests.containsKey(id)) {
			Collection<DeferredResult<String>> deferredResults = watchRequests.get(id);
			for (DeferredResult<String> deferredResult : deferredResults) {
				deferredResult.setResult("我更新了" + new Date());
			}
		}
		return "success";
	}
}

